/*
 *  shnodeui_qt.h
 *  shaderz_v3
 *
 *  Created by Anjali on 4/15/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef __SH_NODE_UI_QT_H__
#define __SH_NODE_UI_QT_H__

#include <QtGui/QWidget>
#include <QGLWidget>
#include <QtGui/QMoveEvent>

#include "shnode.h"

namespace shaderzui
{
	// possible interactions with a link stub
	enum shStubInteraction { SHSI_MousePressed=0, SHSI_MouseReleased, SHSI_MouseMove, SHSI_MouseEnter, SHSI_MouseLeave, SHSI_TryNewConnection };
	
	namespace qt
	{
		// simple widget class to emit a mouseDown signal 
		class simpleStubWidget : public QWidget
		{
			Q_OBJECT
			
		signals:
			void stubInteraction( shStubInteraction InInteraction );	// some interaction was performed with the stub
			
		public:
			simpleStubWidget(QWidget* InParent, const QColor& InNormalColor, const QColor& InHoverColor );
			
		protected:
			virtual void mousePressEvent( QMouseEvent* InEventInfo );
			virtual void mouseMoveEvent( QMouseEvent* InEventInfo );
			virtual void mouseReleaseEvent( QMouseEvent* InEventInfo );
			virtual void enterEvent( QEvent* InEventInfo );
			virtual void leaveEvent( QEvent* InEventInfo );
			virtual void paintEvent( QPaintEvent* InEventInfo );
			
		protected:
			bool			mIsMouseOver;
			const QColor	mNormalColor;
			const QColor	mHoverColor;
			
		private: 
			typedef QWidget	ParentClass;
		};
		
		// class for representing the link stub
		class linkStubUI : public QWidget
		{
			friend class		shNodeUI;
			static const int	LINKSTUBSIZE;
		
			// allow for singmals and slots
			Q_OBJECT
			
		signals:
			void stubInteraction( shStubInteraction InInteraction, linkStubUI* InStubUI );	// some interaction was performed with the internal stub
			
		public slots:
			void onStubInteraction( shStubInteraction InInteraction );
			
		public:
			enum alignMode { STUBALIGN_LEFT=0, STUBALIGN_RIGHT };
				
		public:
			linkStubUI( QWidget* InParent, shaderz::shNode::linkStub* InLinkStub, alignMode InAlignMode = STUBALIGN_LEFT );
			const shaderz::shNode::linkStub*	linkStub() const { return mLinkStub; }
			QPoint	getStubPos() const;
			alignMode	getAlignMode() const { return mAlignMode; }
		
		protected:
			shaderz::shNode::linkStub*	mLinkStub;
			alignMode					mAlignMode;
			simpleStubWidget*			mInternalStubWidget;
						
		private:
			typedef QWidget ParentClass;
		};
		
		// class for preview section of the node
		class nodePreviewWidget : public QWidget
		{
			Q_OBJECT
			
		signals:
			void clicked();
			
		public:
			enum PreviewType { SHPT_Const=0, SHPT_Color, SHPT_Texture };
		
		public:
			nodePreviewWidget( QWidget* InParentnodePreviewWidget );
		
			// setters
			void setPreviewType( PreviewType InPreviewType );
			void setSolidColor( QColor InNewColor, bool InShouldUpdate );
		
			// getters
			const QColor&	getSolidColor() const { return mSolidColor; }
			
		protected:
			virtual void mouseReleaseEvent(QMouseEvent* InEventInfo);
			virtual void paintEvent(QPaintEvent* InEventInfo);
		
		protected:
			PreviewType	mPreviewType;
			QColor		mSolidColor;	// only applicable for constants and color nodes
		
		private:
			typedef QWidget	ParentClass;
		};
	
		// class for representing a generic node
		class shNodeUI : public QWidget
		{
			Q_OBJECT
			
		signals:
			void nodeUIMoved();	// indicated that the nodeUI has moved
			void nodeUIDeleted( unsigned int InCoreNodeAddress );	// emitted from the destructor of the nodeUI
			void stubInteraction( shStubInteraction InInteraction, linkStubUI* InStubUI, shNodeUI* InNodeUI );	// some interaction was performed with a stub within the node
			
		public slots:
			virtual void onStubInteraction( shStubInteraction InInteraction, linkStubUI* InSelectedStubUI);
			virtual void onPreviewWidgetClicked();
			
		public:
			shNodeUI( QWidget* InParent, shaderz::shNode* InNode );
			virtual ~shNodeUI();
			linkStubUI* findUIForStub( const shaderz::shNode::linkStub* InLinkStub ) const;
			shaderz::shNode* node() { return mNode; }
			
		protected:
			virtual void moveEvent( QMoveEvent* InEventInfo );
			
		protected:
			nodePreviewWidget*			mPreviewWidget;
			shaderz::shNode*			mNode;
			std::vector<linkStubUI*>	mAllStubs;
			
			const static int WIDGETSIZE;
			
		private:
			typedef QWidget	ParentClass;
		};
	}
}

#endif
